package com.bw.lib_http

import android.os.Environment
import com.tencent.mmkv.MMKV
import com.zyj.retrofit.adapter.FlowCallAdapterFactory
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.ResponseBody.Companion.toResponseBody
import okhttp3.logging.HttpLoggingInterceptor
import org.json.JSONObject
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.net.Proxy
import java.security.SecureRandom
import java.security.cert.X509Certificate
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLHandshakeException
import javax.net.ssl.SSLSocketFactory
import javax.net.ssl.X509TrustManager

/**
 * OkHttpClient管理类
 */

object OkHttpClientManager {

    /**
     * 普通的Http请求的客户端
     */

    val httpClientInstance: OkHttpClient by lazy {
        createOkHttpClient()
    }

    fun createOkHttpClient(): OkHttpClient {
        var okBuilder = OkHttpClient.Builder()
            .apply {
                connectTimeout(1000, TimeUnit.SECONDS)

                readTimeout(1000, TimeUnit.SECONDS)

                writeTimeout(1000, TimeUnit.SECONDS)

                //设置接口请求拦截日志
//                if (BuildConfig.isOpenLog){
//                    addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))//日志拦截器
//                }

                //Header参数拦截器
                addInterceptor(getHeaderInterceptor())

//
//                //服务器异常拦截器
//                addInterceptor(getServiceExceptionInterceptor())
//
//                //添加Https的支持
//                sslSocketFactory(sslSocketFactory, trustManager)
//
//                //设置支持的网络协议
//                protocols(listOf(Protocol.HTTP_2))
//
//                //防止抓包软件获取接口数据
//                proxy(Proxy.NO_PROXY)
//
//                //设置缓存目录
//                val cacheFile= getexternalStoreFile()
//                if (cacheFile != null){
//                    cache(Cache(cacheFile,10 * 1024 * 1024))//10M
//                }

            }
        return okBuilder.build()
    }


    /**
     * 普通的Https请求的客户端
     */

    val httpsClientInstance: OkHttpClient by lazy {
        createOkHttpsClient()
    }

    fun createOkHttpsClient(): OkHttpClient {
        var okBuilder = OkHttpClient.Builder()
            .apply {
                connectTimeout(1000, TimeUnit.SECONDS)

                readTimeout(1000, TimeUnit.SECONDS)

                writeTimeout(1000, TimeUnit.SECONDS)

                //设置接口请求拦截日志

                addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY))//日志拦截器


                //Header参数拦截器
                addInterceptor(getHeaderInterceptor())

                //服务器异常拦截器
                addInterceptor(getServiceExceptionInterceptor())

                //添加Https的支持
                sslSocketFactory(sslSocketFactory, trustManager)

                //设置支持的网络协议
                protocols(listOf(Protocol.HTTP_2))

                //防止抓包软件获取接口数据
                proxy(Proxy.NO_PROXY)

                //设置缓存目录
                val cacheFile = getexternalStoreFile()
                if (cacheFile != null) {
                    cache(Cache(cacheFile, 10 * 1024 * 1024))//10M
                }

            }
        return okBuilder.build()
    }


    /**
     * WebSocket请求客户端
     */
    private val webSocketInstance: OkHttpClient by lazy {
        var wsOkBuilder = OkHttpClient.Builder().apply {
            //设置心跳间隔时间，维持长连接
            pingInterval(10, TimeUnit.SECONDS)
        }
        wsOkBuilder.build()
    }


    /**
     * 发起WebSocket请求
     */
    fun createWebSocketRequest(webSocketUrl: String, listener: WebSocketListener) {
        val requestBuilder = Request.Builder().apply {
            url(webSocketUrl)
        }
        webSocketInstance.newWebSocket(requestBuilder.build(), listener)
    }


    /**
     * Retrofit实例
     */
    val retrofitInstance: Retrofit by lazy {
        Retrofit.Builder().apply {
            baseUrl("http://10.161.9.80:7015/")
            client(httpClientInstance)
            addConverterFactory(GsonConverterFactory.create())
            addCallAdapterFactory(FlowCallAdapterFactory.create())
        }.build()
    }

    /**
     * 对外提供创建Retrofit实例的方法
     */
    fun createRetrofit(okHttpClient: OkHttpClient): Retrofit {
        return Retrofit.Builder().apply {
            baseUrl("http://10.161.9.80:7015/")
            client(okHttpClient)
            addConverterFactory(GsonConverterFactory.create())
        }.build()
    }


    private fun getexternalStoreFile(): File? {
        val externalStoreFile = Environment.getExternalStorageDirectory()
        if (externalStoreFile.exists()) return File(externalStoreFile, "park_network_cache")
        return null
    }


    private val sslSocketFactory: SSLSocketFactory
        get() = try {
            val sslContext = SSLContext.getInstance("SSL")
            sslContext.init(null, arrayOf(trustManager), SecureRandom())
            sslContext.socketFactory
        } catch (e: Exception) {
            throw RuntimeException(e)
        }


    private val trustManager: X509TrustManager
        get() = object : X509TrustManager {
            /**
             * 检查客户端的证书
             */
            override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {
            }

            /**
             * 检查服务端的证书
             */
            override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {
                //防止抓包工具，如Fiddler, Charles抓取数据
                chain?.forEach { certificate ->
                    if (certificate.issuerX500Principal.name.contains("Charles") ||
                        certificate.issuerX500Principal.name.contains("Fiddler")
                    ) {
                        throw SSLHandshakeException("Fiddler或Charles证书被拒绝")
                    }
                }
            }

            override fun getAcceptedIssuers(): Array<X509Certificate> {
                return arrayOf()
            }
        }


    /**
     * 请求头拦截器
     */

    private fun getHeaderInterceptor(): Interceptor {
        return object : Interceptor {
            override fun intercept(chain: Interceptor.Chain): Response {
                //获取Token
                var token = MMKV.defaultMMKV().decodeString("token", "a2208_park")
                val newBuilder = chain.request().newBuilder()
                if (token != null) {
                    newBuilder.header("token", token).build()
                }

                //获取AccessId
                var accessId =
                    MMKV.defaultMMKV().decodeString("accessId", "dd3aba2abb8b449784cf632fbedbf583")
                if (accessId != null) {
                    newBuilder.header("accessId", accessId).build()
                }

                //执行请求
                val newRequest = newBuilder.build()
                val response = chain.proceed(newRequest)

                //验证Token是否过期
                if (response.code == 403 || response.code == 401) {
//                    ARouter.getInstance().build(RouterConst.PATH_LOGIN_ACTIVITY).navigation()
                }

                return response
            }

        }
    }

    /**
     * 服务器异常拦截器
     * Interceptor属于责任链模式
     */
    private fun getServiceExceptionInterceptor(): Interceptor {
        return object : Interceptor {
            override fun intercept(chain: Interceptor.Chain): Response {
                var errorResponse = chain.proceed(chain.request())
                var responseBuilder = errorResponse.newBuilder()
                if (errorResponse.code == 500) {
                    var newJson = JSONObject()
                    newJson.put("code", 500)
                    newJson.put("message", "服务器异常，请联系客服！")
                    responseBuilder.body(
                        newJson.toString()
                            .toResponseBody("application/json;charset=UTF-8".toMediaTypeOrNull())
                    )
                }

                return responseBuilder.build()
            }

        }
    }

    fun clearAllRequest() {
        httpClientInstance?.dispatcher?.run {
            cancelAll()//取消请求
            executorService.shutdown()//关闭线程池
        }

        httpsClientInstance?.dispatcher?.run {
            cancelAll()//取消请求
            executorService.shutdown() //关闭线程池
        }

        webSocketInstance.dispatcher?.run {
            cancelAll()//取消请求
            executorService.shutdown()//关闭线程池
        }

        //关闭缓存
        httpClientInstance?.cache?.close()
        httpsClientInstance?.cache?.close()
        webSocketInstance?.cache?.close()


    }

}